package com.jstyle.devicenametest

import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothAdapter.LeScanCallback
import android.bluetooth.BluetoothManager
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.jstyle.devicenametest.ble.BleManager
import com.jstyle.devicenametest.ble.BleService
import com.jstyle.devicenametest.db.DataDbHelper
import com.jstyle.devicenametest.db.entiy.ExitAddress
import com.jstyle.devicenametest.db.entiy.VibAddress
import com.jstyle.devicenametest.utils.*
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_main.*
import java.util.*

class MainActivity : AppCompatActivity(), PermissionsUtil.PermissionListener {
    var deviceCount=0;
    lateinit var mBluetoothAdapter: BluetoothAdapter;
    lateinit var resetDeviceList: MutableList<ExitAddress>;
    lateinit var vibDeviceList: MutableList<VibAddress>;
    lateinit var connectAddress: String;
    var isScanning = false;
    lateinit var disposable: Disposable;
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        BleManager.init(this)
        DataDbHelper.getInstance(this).initDb()
        init();
    }

    fun init() {

        checkPermissions()
        // Initializes a Bluetooth adapter. For API level 18 and above, get a
        // reference to
        // BluetoothAdapter through BluetoothManager.
        val bluetoothManager = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
        mBluetoothAdapter = bluetoothManager.adapter

        resetDeviceList = DataDbHelper.getInstance().exitDao.loadAllAddress();
        vibDeviceList = DataDbHelper.getInstance().vibDao.loadAllAddress();
        resetDeviceList.forEach {
            Log.i(TAG, "init: reset ${it.address}")
        }
        vibDeviceList.forEach {
            Log.i(TAG, "init: vib ${it.address}")
        }
        bt_StartScan.setOnClickListener {
            startScan();
        }
        bt_StopScan.setOnClickListener {
            stopScan()
        }
        bt_ShareFile.setOnClickListener {
            shareFile()
        }
        RxBus.getInstance().toObservable(BleData::class.java).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread()).subscribe(object : Observer<BleData> {
                override fun onSubscribe(d: Disposable) {
                    disposable = d
                }

                override fun onNext(bleData: BleData) {
                    val action: String = bleData.getAction()
                    if (action == BleService.ACTION_DATA_AVAILABLE) {
                        val value: ByteArray = bleData.getValue()
                        if (value[0] == 0x4d.toByte()) {
                            BleManager.getInstance().disconnectDevice()
                        }
                    } else if (action == BleService.ACTION_GATT_DISCONNECTED) {
                        tvInfo.append("DISCONNECTED:${bleData.data} \n")
                        startScan()
                    } else if (action == BleService.ACTION_GATT_onDescriptorWrite) {
                        Log.i(TAG, "onNext: ${bleData.data}")
                        deviceCount++;
                        tvCount.text = "DeviceCount $deviceCount";
                        checkDeviceAddress(bleData.data)
                    }
                }

                override fun onError(e: Throwable) {}
                override fun onComplete() {}
            })

    }

    override fun onDestroy() {
        super.onDestroy()
        unSubscribe(disposable)
    }

    protected fun unSubscribe(disposable: Disposable?) {
        if (disposable != null && !disposable.isDisposed) {
            disposable.dispose()
        }
    }

    private fun startScan() {
        if (!mBluetoothAdapter.isEnabled) {
            if (!mBluetoothAdapter.isEnabled) {
                val enableBtIntent = Intent(
                    BluetoothAdapter.ACTION_REQUEST_ENABLE
                )
                startActivityForResult(enableBtIntent, 1111)
            }
            return
        }
        if (!isGant||isScanning) return
        isStartConnect=false
        mBluetoothAdapter.startLeScan(mLeScanCallback)
        //	mBluetoothAdapter.startLeScan(serviceUuids, mLeScanCallback);
        isScanning = true
        tvInfo.append("StartScan \n");
    }
    fun checkPermissions(){
        PermissionsUtil.requestPermissions(
            this, this,
            Manifest.permission.ACCESS_FINE_LOCATION
        );
    }
    fun stopScan(){
        if(!isScanning)return
        mBluetoothAdapter.stopLeScan(mLeScanCallback)
        isScanning=false;
        tvInfo.append("stopScan \n");
    }

    fun isExist(deviceAddress: String): Boolean {
        var isExit = false;
        resetDeviceList.forEach {
            if (it.address == deviceAddress) isExit = true;
        }
        return isExit;
    }

    fun isVibExist(deviceAddress: String): Boolean {
        var isExit = false;
        vibDeviceList.forEach {
            if (it.address == deviceAddress) isExit = true;
        }
        return isExit;
    }

    //判断mac地址是否重复
    //不在之前的扫描列表里面就发送休眠指令，并保存mac地址
    //在之前的扫描列表里就发送4d指令震动设备，并保存mac地址到另外一个数据库
    fun checkDeviceAddress(deviceAddress: String) {
        when (isExist(deviceAddress)) {
            true -> vibDevice(deviceAddress)
            else -> resetDevice(deviceAddress)
        }
    }

    fun resetDevice(deviceAddress: String) {
        var exitAddress = ExitAddress();
        exitAddress.address = deviceAddress;
        resetDeviceList.add(exitAddress)
        DataDbHelper.getInstance().exitDao.insert(exitAddress)
        BleManager.getInstance().writeValue(SendData.reset())
    }

    fun vibDevice(deviceAddress: String) {
        var vibAddress = VibAddress();
        vibAddress.address = deviceAddress;
        vibDeviceList.add(vibAddress)
        DataDbHelper.getInstance().vibDao.insert(vibAddress)
        BleManager.getInstance().writeValue(SendData.notifyDevice())

    }

    // Adapter for holding devices found through scanning.
    // Device scan callback.
    private  val TAG = "MainActivity"
    var isStartConnect=false;
    var filterName="GOQii SV Plus";
    private val mLeScanCallback =
        LeScanCallback { device, rssi, scanRecord ->
            runOnUiThread(Runnable {
                Log.i(TAG, ": ${device.address}")
                var name = device.name;
                if (TextUtils.isEmpty(name)) {
                    name = SendData.decodeDeviceName(scanRecord);
                }
                Log.i(TAG, "name: $name ")
                if (!TextUtils.isEmpty(name) && name.toLowerCase()
                        .contains(filterName.toLowerCase())
                ) {
                    var isVibExit = isVibExist(device.address)
                    if (!isVibExit && !isStartConnect) {
                        isStartConnect = true;
                        stopScan();
                        tvInfo.append("StartConnected:${device.address} \n")
                        BleManager.getInstance().connectDevice(device.address)
                    }
                }
            })
        }
    var isGant=false;
    override fun granted(name: String?) {
        isGant=true;

    }

    override fun NeverAskAgain() {

    }

    override fun disallow(name: String?) {

    }
    fun shareFile(){
        val path = "Mac" + System.currentTimeMillis() + ".csv"
        val contentList: MutableList<Array<String?>> = ArrayList()
        val title = arrayOfNulls<String>(1)
        title[0]="Mac";
        resetDeviceList.forEach {
            val content = arrayOfNulls<String>(1);
            content[0]=it.address;
            contentList.add(content);
        }
        CsvUtils.shareFile(this, contentList, title, path);
    }

}